home *** CD-ROM | disk | FTP | other *** search
- .model small,pascal
-
- if @DataSize
-
- LES_ equ les
- ES_ equ es:
- PUSH_ macro x
- push word ptr (x)+2
- push word ptr (x)
- endm
-
- else
-
- LES_ equ mov
- ES_ equ ds:
- PUSH_ macro x
- push x
- endm
-
- endif
-
- quad struc
- q0 dw ?
- q1 dw ?
- q2 dw ?
- q3 dw ?
- quad ends
-
- .code
-
- ;-----------------------------------------------------------------------------
- ;void pascal quadinc(quad* z, quad x)
- ;compute z=z+x
-
- public QUADINC
- QUADINC proc z:ptr, x:qword
-
- LES_ bx,z
- mov ax,(x).q0
- add ES_[bx].q0,ax
- mov ax,(x).q1
- adc ES_[bx].q1,ax
- mov ax,(x).q2
- adc ES_[bx].q2,ax
- mov ax,(x).q3
- adc ES_[bx].q3,ax
- ret
-
- QUADINC endp
-
- ;-----------------------------------------------------------------------------
- ;void pascal quadinca(quad* z, quad* x)
- ;compute z=z+x
-
- public QUADINCA
- QUADINCA proc uses si, z:ptr, x:ptr
-
- LES_ si,x
- mov ax,ES_[si].q0
- mov bx,ES_[si].q1
- mov cx,ES_[si].q2
- mov dx,ES_[si].q3
- LES_ si,z
- add ES_[si].q0,ax
- adc ES_[si].q1,bx
- adc ES_[si].q2,cx
- adc ES_[si].q3,dx
- ret
-
- QUADINCA endp
-
- ;-----------------------------------------------------------------------------
- ;void pascal quaddec(quad* z, quad x)
- ;compute z=z-x
-
- public QUADDEC
- QUADDEC proc z:ptr, x:qword
-
- LES_ bx,z
- mov ax,(x).q0
- sub ES_[bx].q0,ax
- mov ax,(x).q1
- sbb ES_[bx].q1,ax
- mov ax,(x).q2
- sbb ES_[bx].q2,ax
- mov ax,(x).q3
- sbb ES_[bx].q3,ax
- ret
-
- QUADDEC endp
-
- ;-----------------------------------------------------------------------------
- ;void pascal quaddeca(quad* z, quad* x)
- ;compute z=z-x
-
- public QUADDECA
- QUADDECA proc uses si, z:ptr, x:ptr
-
- LES_ si,x
- mov ax,ES_[si].q0
- mov bx,ES_[si].q1
- mov cx,ES_[si].q2
- mov dx,ES_[si].q3
- LES_ si,z
- sub ES_[si].q0,ax
- sbb ES_[si].q1,bx
- sbb ES_[si].q2,cx
- sbb ES_[si].q3,dx
- ret
-
- QUADDECA endp
-
- ;-----------------------------------------------------------------------------
- ;void pascal quadadd(quad* z, quad x, quad y)
- ;compute z=x+y
-
- public QUADADD
- QUADADD proc z:ptr, x:qword, y:qword
-
- LES_ bx,z
- mov ax,(x).q0
- add ax,(y).q0
- mov ES_[bx].q0,ax
- mov ax,(x).q1
- adc ax,(y).q1
- mov ES_[bx].q1,ax
- mov ax,(x).q2
- adc ax,(y).q2
- mov ES_[bx].q2,ax
- mov ax,(x).q3
- adc ax,(y).q3
- mov ES_[bx].q3,ax
- ret
-
- QUADADD endp
-
- ;-----------------------------------------------------------------------------
- ;void pascal quadadda(quad* z, quad* x, quad* y)
- ;compute z=x+y
-
- public QUADADDA
- QUADADDA proc uses si, z:ptr, x:ptr, y:ptr
-
- LES_ si,x
- mov ax,ES_[si].q0
- mov bx,ES_[si].q1
- mov cx,ES_[si].q2
- mov dx,ES_[si].q3
- LES_ si,y
- add ax,ES_[si].q0
- adc bx,ES_[si].q1
- adc cx,ES_[si].q2
- adc dx,ES_[si].q3
- LES_ si,z
- mov ES_[si].q0,ax
- mov ES_[si].q1,bx
- mov ES_[si].q2,cx
- mov ES_[si].q3,dx
- ret
-
- QUADADDA endp
-
- ;-----------------------------------------------------------------------------
- ;void pascal quadsub(quad* z, quad x, quad y)
- ;compute z=x-y
-
- public QUADSUB
- QUADSUB proc z:ptr, x:qword, y:qword
-
- LES_ bx,z
- mov ax,(x).q0
- sub ax,(y).q0
- mov ES_[bx].q0,ax
- mov ax,(x).q1
- sbb ax,(y).q1
- mov ES_[bx].q1,ax
- mov ax,(x).q2
- sbb ax,(y).q2
- mov ES_[bx].q2,ax
- mov ax,(x).q3
- sbb ax,(y).q3
- mov ES_[bx].q3,ax
- ret
-
- QUADSUB endp
-
- ;-----------------------------------------------------------------------------
- ;void pascal quadsuba(quad* z, quad* x, quad* y)
- ;compute z=x-y
-
- public QUADSUBA
- QUADSUBA proc uses si, z:ptr, x:ptr, y:ptr
-
- LES_ si,x
- mov ax,ES_[si].q0
- mov bx,ES_[si].q1
- mov cx,ES_[si].q2
- mov dx,ES_[si].q3
- LES_ si,y
- sub ax,ES_[si].q0
- sbb bx,ES_[si].q1
- sbb cx,ES_[si].q2
- sbb dx,ES_[si].q3
- LES_ si,z
- mov ES_[si].q0,ax
- mov ES_[si].q1,bx
- mov ES_[si].q2,cx
- mov ES_[si].q3,dx
- ret
-
- QUADSUBA endp
-
- ;-----------------------------------------------------------------------------
- ;void pascal quadmult(quad* z, quad x, quad y)
- ;compute z=x*y
-
- public QUADMULT
- QUADMULT proc uses si di, z:ptr, x:qword, y:qword
-
- LES_ bx,z
-
- mov di,(x).q0
- mov si,(y).q0
-
- mov ax,di
- mul si ;x0*y0
- mov ES_[bx].q0,ax
- mov cx,dx
-
- mov ax,di
- mul (y).q1 ;x0*y1
- add cx,ax
- adc dx,0
-
- mov ax,si
- mov si,dx
- mul (x).q1 ;x1*y0
- add cx,ax
- adc si,dx
- mov ES_[bx].q1,cx
- mov cx,0
- rcl cx,1
-
- mov ax,di
- mul (y).q2 ;x0*y2
- add si,ax
- adc cx,dx
-
- mov ax,di
- mul (y).q3 ;x0*y3
- add cx,ax
-
- mov ax,(x).q1
- mul (y).q1 ;x1*y1
- add si,ax
- adc cx,dx
-
- mov di,(x).q2
- mov ax,di
- mul (y).q0 ;x2*y0
- add si,ax
- mov ES_[bx].q2,si
- adc cx,dx
-
- mov ax,(x).q1
- mul (y).q2 ;x1*y2
- add cx,ax
-
- mov ax,di
- mul (y).q1 ;x2*y1
- add cx,ax
-
- mov ax,(x).q3
- mul (y).q0 ;x3*y0
- add cx,ax
- mov ES_[bx].q3,cx
-
- ret
-
- QUADMULT endp
-
- ;-----------------------------------------------------------------------------
- ;void pascal quadmulta(quad* z, quad* x, quad* y)
- ;compute z=x*y
-
- public QUADMULTA
- QUADMULTA proc z:ptr, x:ptr, y:ptr
-
- PUSH_ z
- LES_ bx,x
- push ES_[bx].q3
- push ES_[bx].q2
- push ES_[bx].q1
- push ES_[bx].q0
- LES_ bx,y
- push ES_[bx].q3
- push ES_[bx].q2
- push ES_[bx].q1
- push ES_[bx].q0
- call QUADMULT
-
- ret
-
- QUADMULTA endp
-
- ;-----------------------------------------------------------------------------
- ;void pascal quaddiv(quad* z, quad x, quad y)
- ;compute z=x/y
-
- public QUADDIV
- QUADDIV proc uses si di, z:ptr, x:qword, y:qword
- local zz:qword
- local sign:byte
-
- mov sign,0
-
- mov cx,(x).q3 ;check sign of x
- or cx,cx
- jns quaddiv01
-
- inc sign
- xor ax,ax
- mov dx,ax
- mov bx,ax
- mov cx,ax
- sub ax,(x).q0
- sbb dx,(x).q1
- sbb bx,(x).q2
- sbb cx,(x).q3
- mov (x).q0,ax
- mov (x).q1,dx
- mov (x).q2,bx
- mov (x).q3,cx
- quaddiv01:
- mov cx,(y).q3 ;check sign of y
- or cx,cx
- jns quaddiv02
-
- inc sign
- xor ax,ax
- mov dx,ax
- mov bx,ax
- mov cx,ax
- sub ax,(y).q0
- sbb dx,(y).q1
- sbb bx,(y).q2
- sbb cx,(y).q3
- mov (y).q0,ax
- mov (y).q1,dx
- mov (y).q2,bx
- mov (y).q3,cx
- quaddiv02:
-
- ;---------------------------------------
- jcxz quaddiv03
- jmp quaddiv36 ;2^48 <= y
- quaddiv03:
- mov cx,(y).q2
- jcxz quaddiv04
- jmp quaddiv25 ;2^32 <= y < 2^48
- quaddiv04:
- mov cx,(y).q1
- jcxz quaddiv05
- jmp quaddiv07 ;2^16 <= y < 2^32
- quaddiv05:
- mov cx,(y).q0
- jcxz quaddiv06
-
- ;---------------------------------------
- ;y < 2^16:
-
- xor dx,dx
- mov ax,(x).q3
- div cx
- mov di,ax
- mov ax,(x).q2
- div cx
- mov si,ax
- mov ax,(x).q1
- div cx
- mov bx,ax
- mov ax,(x).q0
- div cx
- mov dx,bx
- jmp quaddiv40
- quaddiv06:
- jmp quaddiv42
-
- ;---------------------------------------
- ;2^16 <= y < 2^32:
-
- quaddiv07:
- mov bx,(y).q0
- mov dx,(x).q3
- mov ax,(x).q2
- quaddiv08:
- shr cx,1 ;shift right x and y until y < 2^16
- rcr bx,1
- shr dx,1
- rcr ax,1
- or cx,cx
- jnz quaddiv08
-
- div bx ;estimate (z).q2
- or ax,ax
- jz quaddiv10
- mov di,ax ;multiply y by (z).q2
- mul (y).q0
- mov bx,ax
- mov cx,dx
- mov ax,(y).q1
- mul di
- add cx,ax
-
- mov dx,(x).q2 ;subtract product from x
- mov si,(x).q3
- sub dx,bx
- sbb si,cx
- jnc quaddiv09
-
- dec di ;decrement (z).q2 if (z).q2*y > x
- add dx,(y).q0
- adc si,(y).q1
- quaddiv09:
- mov (x).q2,dx ;store x
- mov (x).q3,si
- mov (zz).q2,di
- jmp quaddiv11
- quaddiv10:
- mov (zz).q2,ax
- mov si,(x).q3
- mov dx,(x).q2
-
- ;-----------------------
- quaddiv11:
- mov ax,(x).q1
- mov cx,(y).q1
- mov bx,(y).q0
- quaddiv12:
- shr cx,1 ;shift right x and y until y < 2^16
- rcr bx,1
- shr si,1
- rcr dx,1
- rcr ax,1
- or cx,cx
- jnz quaddiv12
-
- cmp dx,bx
- jb quaddiv13
- mov ax,0ffffh
- jmp quaddiv14
- quaddiv13:
- div bx ;estimate (z).q1
- quaddiv14:
- mov (zz).q1,ax
- or ax,ax
- jz quaddiv17
- mov di,ax ;multiply y by (z).q1
- mul (y).q0
- mov bx,ax
- mov cx,dx
- mov ax,(y).q1
- mul di
- xor si,si
- add cx,ax
- adc si,dx
-
- mov dx,(x).q1 ;subtract product from x
- mov di,(x).q2
- mov ax,(x).q3
- sub dx,bx
- sbb di,cx
- sbb ax,si
- jnc quaddiv16
- quaddiv15:
- dec (zz).q1 ;decrement (z).q1 if (z).q1*y > x
- add dx,(y).q0
- adc di,(y).q1
- adc ax,0
- jnc quaddiv15
- quaddiv16:
- mov (x).q1,dx ;store x
- mov (x).q2,di
- jmp quaddiv18
- quaddiv17:
- mov di,(x).q2
- mov dx,(x).q1
-
- ;-----------------------
- quaddiv18:
- mov ax,(x).q0
- mov cx,(y).q1
- mov bx,(y).q0
- quaddiv19:
- shr cx,1 ;shift right x and y until y < 2^16
- rcr bx,1
- shr di,1
- rcr dx,1
- rcr ax,1
- or cx,cx
- jnz quaddiv19
-
- cmp dx,bx
- jb quaddiv20
- mov ax,0ffffh
- jmp quaddiv21
- quaddiv20:
- div bx ;estimate (z).q0
- or ax,ax
- jz quaddiv24
- quaddiv21:
- mov (zz).q0,ax
- mov di,ax ;multiply y by (z).q0
- mul (y).q0
- mov bx,ax
- mov cx,dx
- mov ax,(y).q1
- mul di
- xor si,si
- add cx,ax
- adc si,dx
-
- mov dx,(x).q0 ;subtract product from x
- mov di,(x).q1
- mov ax,(x).q2
- sub dx,bx
- sbb di,cx
- sbb ax,si
- jnc quaddiv23
- quaddiv22:
- dec (zz).q0 ;decrement (z).q0 if (z).q0*y > x
- add dx,(y).q0
- adc di,(y).q1
- adc ax,0
- jnc quaddiv22
- quaddiv23:
- mov ax,(zz).q0
- quaddiv24:
- mov dx,(zz).q1
- mov si,(zz).q2
- xor di,di
- jmp quaddiv40
-
- ;---------------------------------------
- ;2^32 <= y < 2^48:
-
- quaddiv25:
- mov bx,(y).q1
- mov dx,(x).q3
- mov ax,(x).q2
- quaddiv26:
- shr cx,1 ;shift right x and y until y < 2^32
- rcr bx,1
- shr dx,1
- rcr ax,1
- or cx,cx
- jnz quaddiv26
-
- div bx ;estimate (z).q1
- mov (zz).q1,ax
- or ax,ax
- jz quaddiv28
- mov di,ax ;multiply y by (z).q1
- mul (y).q0
- mov bx,ax
- mov cx,dx
- mov ax,(y).q1
- mul di
- xor si,si
- add cx,ax
- adc si,dx
- mov ax,(y).q2
- mul di
- add si,ax
-
- mov ax,(x).q1 ;subtract product from x
- mov dx,(x).q2
- mov di,(x).q3
- sub ax,bx
- sbb dx,cx
- sbb di,si
- jnc quaddiv27
-
- dec (zz).q1 ;decrement (z).q1 if too large
- add ax,(y).q0
- adc dx,(y).q1
- adc di,(y).q2
- quaddiv27:
- mov (x).q1,ax ;store x
- mov (x).q2,dx
- mov (x).q3,di
- jmp quaddiv29
- quaddiv28:
- mov di,(x).q3
- mov dx,(x).q2
- mov ax,(x).q1
-
- ;-----------------------
- quaddiv29:
- mov cx,(y).q2
- mov bx,(y).q1
- quaddiv30:
- shr cx,1 ;shift right x and y until y < 2^32
- rcr bx,1
- shr di,1
- rcr dx,1
- rcr ax,1
- or cx,cx
- jnz quaddiv30
-
- cmp dx,bx
- jb quaddiv31
- mov ax,0ffffh
- jmp quaddiv32
- quaddiv31:
- div bx ;estimate (z).q0
- or ax,ax
- jz quaddiv35
- quaddiv32:
- mov (zz).q0,ax
- mov di,ax ;multiply y by (z).q0
- mul (y).q0
- mov bx,ax
- mov cx,dx
- mov ax,(y).q1
- mul di
- xor si,si
- add cx,ax
- adc si,dx
- mov ax,(y).q2
- mul di
- add si,ax
- adc dx,0
-
- mov ax,(x).q0 ;subtract product from x
- mov di,(x).q1
- sub ax,bx
- sbb di,cx
- sbb (x).q2,si
- sbb (x).q3,dx
- jnc quaddiv34
-
- mov bx,(x).q2
- mov cx,(x).q3
- quaddiv33:
- dec (zz).q0 ;decrement (z).q0 if (z).q0*y > x
- add ax,(y).q0
- adc di,(y).q1
- adc bx,(y).q2
- adc cx,0
- jnc quaddiv33
- quaddiv34:
- mov ax,(zz).q0
- quaddiv35:
- mov dx,(zz).q1
- xor si,si
- mov di,si
- jmp quaddiv40
-
- ;---------------------------------------
- ;2^48 <= y:
-
- quaddiv36:
- mov bx,(y).q2
- mov dx,(x).q3
- mov ax,(x).q2
- quaddiv37:
- shr cx,1 ;shift right x and y until y < 2^48
- rcr bx,1
- shr dx,1
- rcr ax,1
- or cx,cx
- jnz quaddiv37
-
- div bx ;estimate z
- or ax,ax
- jz quaddiv39
- mov (zz).q0,ax
- mov di,ax ;multiply y by z
- mul (y).q0
- mov bx,ax
- mov cx,dx
- mov ax,(y).q1
- mul di
- xor si,si
- add cx,ax
- adc si,dx
- mov ax,(y).q2
- mul di
- add si,ax
- adc dx,0
- xchg dx,di
- mov ax,(y).q3
- mul dx
- add di,ax
-
- mov ax,(zz).q0
- cmp di,(x).q3
- ja quaddiv38
- jb quaddiv39
- cmp si,(x).q2
- ja quaddiv38
- jb quaddiv39
- cmp cx,(x).q1
- ja quaddiv38
- jb quaddiv39
- cmp bx,(x).q0
- jbe quaddiv39
- quaddiv38:
- dec ax ;decrement z if z*y > x
- quaddiv39:
- xor dx,dx
- mov si,dx
- mov di,dx
-
- ;---------------------------------------
- quaddiv40:
- test sign,1
- jz quaddiv41
-
- xor cx,cx ;change sign of result
- neg ax
- adc dx,cx
- adc si,cx
- adc di,cx
- neg dx
- adc si,cx
- adc di,cx
- neg si
- adc di,cx
- neg di
-
- quaddiv41:
- LES_ bx,z
- mov ES_[bx].q0,ax
- mov ES_[bx].q1,dx
- mov ES_[bx].q2,si
- mov ES_[bx].q3,di
-
- ret
-
- quaddiv42: ;divide error
- xor ax,ax
- dec ax
- cwd
- mov si,ax
- mov di,7fffh
- jmp quaddiv40 ;return 7fffffffffffffffh
-
- QUADDIV endp
-
- ;-----------------------------------------------------------------------------
- ;void pascal quaddiva(quad* z, quad* x, quad* y)
- ;compute z=x*y
-
- public QUADDIVA
- QUADDIVA proc z:ptr, x:ptr, y:ptr
-
- PUSH_ z
- LES_ bx,x
- push ES_[bx].q3
- push ES_[bx].q2
- push ES_[bx].q1
- push ES_[bx].q0
- LES_ bx,y
- push ES_[bx].q3
- push ES_[bx].q2
- push ES_[bx].q1
- push ES_[bx].q0
- call QUADDIV
-
- ret
-
- QUADDIVA endp
-
- ;-----------------------------------------------------------------------------
- end
-